<script setup>
import { getElementSize } from '@/views/study/three/composables'
import { useResizeObserver } from '@vueuse/core'
import * as THREE from 'three'
import { OrbitControls } from 'three/addons/controls/OrbitControls.js'

const webgl = ref(null)

let renderer = null
let camera = null

onMounted(() => {
  const { width, height } = getElementSize(webgl)

  const scene = new THREE.Scene()
  camera = new THREE.PerspectiveCamera(30, width / height, 0.1, 1000)

  camera.position.set(5, 5, 5)

  renderer = new THREE.WebGLRenderer()
  renderer.setSize(width, height)
  renderer.render(scene, camera)
  webgl.value.appendChild(renderer.domElement)

  const orbit = new OrbitControls(camera, renderer.domElement)
  orbit.enableDamping = true

  const geometry = new THREE.BufferGeometry()
  geometry.setAttribute('position', new THREE.Float32BufferAttribute([
    0,
    0,
    0,
    1,
    0,
    0,
    1,
    1,
    0,
    0,
    1,
    0,
  ], 3))
  geometry.setIndex(new THREE.Uint16BufferAttribute([0, 1, 2, 0, 2, 3], 1))
  geometry.setAttribute('uv', new THREE.Float32BufferAttribute([0, 0, 1, 0, 1, 1, 0, 1], 2))

  const texture = new THREE.TextureLoader().load(new URL('@/assets/uvTexture.png', import.meta.url))

  texture.wrapS = THREE.RepeatWrapping
  texture.wrapT = THREE.RepeatWrapping

  const material = new THREE.MeshBasicMaterial({
    side: THREE.DoubleSide,
    map: texture,
  })

  const mesh = new THREE.Mesh(geometry, material)

  scene.add(mesh)

  const axesHelper = new THREE.AxesHelper(5)
  scene.add(axesHelper)

  function render() {
    requestAnimationFrame(render)

    orbit.update()

    texture.offset.x += 0.001
    texture.offset.y += 0.001

    renderer.render(scene, camera)
  }

  render()
})

function resizeHandler() {
  const { width, height } = getElementSize(webgl)

  camera.aspect = width / height
  camera.updateProjectionMatrix()

  renderer.setSize(width, height)
}

useResizeObserver(webgl, () => {
  resizeHandler()
})
</script>

<template>
  <div ref="webgl" />
</template>
